import os
import os.path as osp

IMG_SIZE = 3000
THRES = 30
area_thres = 15

path_detect_result_log = osp.abspath('./new-results-conf0.1-best-BiCnnNew.txt')
path_true_labels_dir = os.path.abspath('./new_val_txt')


# function: calculate area according to 4 coordinates
def get_area_from_4_points(x1, y1, x2, y2, x3, y3, x4, y4):
    def get_distance(p1, p2):
        return ((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)**0.5
    p1 = [eval(x1), eval(y1)]
    p2 = [eval(x2), eval(y2)]
    p3 = [eval(x3), eval(y3)]
    p4 = [eval(x4), eval(y4)]
    distances = list()  # six combinations
    distances.append(get_distance(p1, p2))
    distances.append(get_distance(p1, p3))
    distances.append(get_distance(p1, p4))
    distances.append(get_distance(p2, p3))
    distances.append(get_distance(p2, p4))
    distances.append(get_distance(p3, p4))
    distances.sort()
    # print(distances)
    # ### # catercorner * 2, longer_edge * 2, shorter_edge * 2
    longer_edge = (distances[2] + distances[3]) / 2
    shorter_edge = (distances[0] + distances[1]) / 2
    area = longer_edge * shorter_edge
    return area


# get detection info from results.txt
with open(path_detect_result_log, 'r') as fp:
    lines = fp.readlines()
pred_info_lst = [line.strip('\n').split(' ') for line in lines]
# print(pred_info_lst[-1])  # [pic_path, class_name, conf, x1, y1, x2, y2, x3, y3, x4, y4]
pred_total_num = len(pred_info_lst)  # Detection 总数


# discard too small predictions
count_tiny = 0
standard_pred_info_lst = []
for pred in pred_info_lst:
    area = get_area_from_4_points(*pred[-8:])
    if area < area_thres * area_thres:
        count_tiny += 1
    else:
        standard_pred_info_lst.append(pred)
print('total number of too small predictions (discarded):', count_tiny)
# print(standard_pred_info_lst[-1])
standard_pred_total_num = len(standard_pred_info_lst)  # Detection 总数


# get true label info from true label dir
true_label_files = os.listdir(path_true_labels_dir)
gt_info_lst = []
for txt_name in true_label_files:
    with open(osp.join(path_true_labels_dir, txt_name), 'r') as fp:
        lines = fp.readlines()
    gt_info_lst.extend(lines)
gt_info_lst = [line.strip('\n').split(' ') for line in gt_info_lst]
# print(gt_info_lst[-1])  # [cls0, x, y, w, h, angle]
gt_total_num = len(gt_info_lst)  # Ground Truth 总数


# 计数总正确的桥的数目
count_correct = 0
for k in range(len(standard_pred_info_lst)):
    pred_box = standard_pred_info_lst[k]
    center_x = (eval(pred_box[-8]) + eval(pred_box[-6]) + eval(pred_box[-4]) + eval(pred_box[-2])) / 4
    center_y = (eval(pred_box[-7]) + eval(pred_box[-5]) + eval(pred_box[-3]) + eval(pred_box[-1])) / 4
    q_cxcy = (center_x, center_y)
    # print('q:', q_cxcy)

    # Search all Ground Truth in this picture
    path_true_label_txt = osp.join(path_true_labels_dir, pred_box[0].split('/')[-1].split('.')[0]+'.txt')
    with open(path_true_label_txt) as fp:
        true_box_lines = fp.readlines()

    count0 = 0
    for true_box_line in true_box_lines:
        true_box = true_box_line.strip('\n').split(' ')
        k_cxcy = (eval(true_box[1]) * IMG_SIZE, eval(true_box[2]) * IMG_SIZE)
        # print('k:', k_cxcy)
        if (k_cxcy[0] - THRES < q_cxcy[0] < k_cxcy[0] + THRES) and (k_cxcy[1] - THRES < q_cxcy[1] < k_cxcy[1] + THRES):
            count0 += 1
    if count0 > 1:
        count0 = 1
    count_correct += count0
    # print('第%d, 有%d个桥准确：' % (k+1, count0))


print('total number of true bridges:', gt_total_num)
print('total number of standard detections:', standard_pred_total_num)
print('correct number of detections:', count_correct)

rate0 = count_correct / gt_total_num
print('检测率:{}%'.format(rate0 * 100))

rate1 = (standard_pred_total_num - count_correct) / standard_pred_total_num
print('虚警率:{}%'.format(rate1 * 100))
